package com.cll.learn.rabbitmq.service.impl;

import com.cll.learn.rabbitmq.entity.Goods;
import com.cll.learn.rabbitmq.entity.Order;
import com.cll.learn.rabbitmq.mapper.GoodsMapper;
import com.cll.learn.rabbitmq.mapper.OrderMapper;
import com.cll.learn.rabbitmq.service.OrderService;
import com.cll.learn.rabbitmq.util.AjaxResult;
import com.cll.learn.rabbitmq.util.UUIDUtils;
import com.cll.learn.rabbitmq.vo.OrderGoodsVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutionException;

/**
 * 描述信息:
 *
 * @author CLL
 * @version 1.0
 * @date 2021/2/23 16:34
 */
@Service
public class OrderServiceImpl implements OrderService {

    private static final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);

    GoodsMapper goodsMapper;

    OrderMapper orderMapper;

    AmqpTemplate amqpTemplate;

    RabbitTemplate rabbitTemplate;

    @Autowired
    public OrderServiceImpl(GoodsMapper goodsMapper, OrderMapper orderMapper, AmqpTemplate amqpTemplate, RabbitTemplate rabbitTemplate) {
        this.goodsMapper = goodsMapper;
        this.orderMapper = orderMapper;
        this.amqpTemplate = amqpTemplate;
        this.rabbitTemplate = rabbitTemplate;
    }

    @Override
    public List<Order> listAll() {
        return orderMapper.selectAll();
    }

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public OrderGoodsVo generateOrder(int goodsId) throws ExecutionException, InterruptedException {
        logger.info("===>>> 生成商品ID={}的订单信息", goodsId);
        OrderGoodsVo result = new OrderGoodsVo();

        Order order = new Order();
        String orderId = UUIDUtils.getUUID();
        order.setId(orderId);
        order.setGoodsId(goodsId);
        order.setState(0);
        order.setStartTime(new Date());
        // TODO 这里不再进行订单的持久化，再消息队列进行持久化
//        orderMapper.insertOrder(order);
        CorrelationData correlationData = new CorrelationData();
        rabbitTemplate.convertAndSend("exchange.order", "routing.order", order, correlationData);

        // 同步等待消息确认
        // 同步等待；可以设置为异步回调
        CorrelationData.Confirm confirm = correlationData.getFuture().get();

        // 判断发送的消息是否得到broke的确认
        boolean isAcked = confirm.isAck();
        if (!isAcked) {
            logger.error("****** 订单消息持久化失败");
            return null;
        }

        // 下单成功之后，发送消息到超时队列中
        rabbitTemplate.convertAndSend("exchange.order.ttl", "routing.order.ttl", order.getId());

        Goods goods = goodsMapper.selectById(goodsId);
        result.setOrder(order);
        result.setGoods(goods);
        return result;
    }

    @Override
    public AjaxResult<String> submitOrder(String orderId) {
        int i = orderMapper.updateState(orderId, 1, new Date(), 0);
        if (i == 1) {
            return new AjaxResult<>(200, "操作成功", "提交订单成功");
        } else {
            return new AjaxResult<>(501, "操作失败");
        }
    }

    @Override
    public AjaxResult<String> cancelOrder(String orderId) {
        int i = orderMapper.updateState(orderId, 2, new Date(), 0);
        if (i == 1) {
            return new AjaxResult<>(200, "操作成功", "取消订单成功");
        } else {
            return new AjaxResult<>(501, "操作失败");
        }
    }
}